package com.ruoyi.ruoyixingyue.modules.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.ConvertUtils;
import com.ruoyi.common.core.utils.page.PageData;
import com.ruoyi.ruoyixingyue.modules.api.entity.Course;
import com.ruoyi.ruoyixingyue.modules.api.entity.CourseType;
import com.ruoyi.ruoyixingyue.modules.api.entity.Teacher;
import com.ruoyi.ruoyixingyue.modules.api.mapper.CourseMapper;
import com.ruoyi.ruoyixingyue.modules.api.po.CourseAdminListPo;
import com.ruoyi.ruoyixingyue.modules.api.po.CourseDictPo;
import com.ruoyi.ruoyixingyue.modules.api.po.CourseInsertPo;
import com.ruoyi.ruoyixingyue.modules.api.po.CourseListPo;
import com.ruoyi.ruoyixingyue.modules.api.service.ICourseService;
import com.ruoyi.ruoyixingyue.modules.api.service.ICourseTypeService;
import com.ruoyi.ruoyixingyue.modules.api.service.ITeacherService;
import com.ruoyi.ruoyixingyue.modules.api.vo.CourseAdminListVo;
import com.ruoyi.ruoyixingyue.modules.api.vo.CourseInsertVo;
import com.ruoyi.ruoyixingyue.modules.api.vo.CourseListVo;
import com.ruoyi.ruoyixingyue.modules.api.vo.CourseUpdateVo;
import com.ruoyi.ruoyixingyue.modules.utils.Condition;
import com.ruoyi.ruoyixingyue.modules.utils.QueryPage;
import com.ruoyi.ruoyixingyue.modules.utils.ValidatorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程表 服务实现类
 * </p>
 *
 * @author lzz
 * @since 2024-02-14
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {


    public final static Map<Integer, String> FREE_MAP = new HashMap<Integer, String>();
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseTypeService typeService;

    @Override
    public R<PageData<CourseListPo>> courseListAPI_001(Condition<CourseListVo> condition) {
        // 构建查询条件
        CourseListVo courseListVo = condition.getCondition();
        QueryPage queryPage = condition.getPage();
        Page<Course> coursePage = new Page<Course>().setCurrent(queryPage.getCurrent()).setSize(queryPage.getSize());
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        // 进行老师的查询
        List<Teacher> userList = teacherService.list(new QueryWrapper<Teacher>().lambda()
                .like(Objects.nonNull(courseListVo.getCourseName()), Teacher::getUserName, courseListVo.getCourseName()));
        Set<Long> teacherIdSet = userList.stream().map(Teacher::getId).collect(Collectors.toSet());
        List<Course> courseByTeacherList = !CollectionUtils.isEmpty(teacherIdSet) ? this.list(queryWrapper.lambda().in(Course::getTeacherId, teacherIdSet)) : new ArrayList<Course>();
        Set<Course> courseByTeacherSet = courseByTeacherList.stream().collect(Collectors.toSet());
        // 进行课程的查询
        List<Course> courseList = this.list(queryWrapper.lambda()
                .like(Objects.nonNull(courseListVo.getCourseName()), Course::getName, courseListVo.getCourseName()));
        Set<Course> courseSet = courseList.stream().collect(Collectors.toSet());

        List<CourseListPo> resultList = new ArrayList<>();
        this.page(coursePage, queryWrapper);
        courseSet.addAll(courseByTeacherSet);
        coursePage.setTotal(courseSet.size());

        // 拿到教师名称
        List<Teacher> teacherList = teacherService.list(new QueryWrapper<Teacher>());
        Map<Long, Teacher> userMap = teacherList.stream().collect(Collectors.toMap(Teacher::getId, teacher -> teacher, (t, t2) -> t2));
        // 构建结果
        courseSet.forEach(course -> {
            CourseListPo resultVo = ConvertUtils.sourceToTarget(course, CourseListPo.class);
            Optional.ofNullable(userMap.get(course.getTeacherId())).ifPresent(user -> {
                resultVo.setTeacherName(user.getUserName());
                resultList.add(resultVo);
            });
        });
        return R.ok(new PageData<>(resultList, coursePage.getTotal()));
    }

    @Override
    public R<List<CourseListPo>> courseTypeListAPI_002(Long id) {
        List<Course> courseList = new ArrayList<>();
        List<CourseListPo> resultList = new ArrayList<>();
        if (id == 0) {
            courseList = this.list(new QueryWrapper<Course>());
        } else {
            courseList = this.list(new QueryWrapper<Course>().lambda().eq(Course::getTypeId, id));
        }
        // 教师名称
        List<Long> teacherIdList = courseList.stream().map(Course::getTeacherId).collect(Collectors.toList());
        List<Teacher> teacherList = !CollectionUtils.isEmpty(teacherIdList) ? teacherService.listByIds(teacherIdList) : new ArrayList<Teacher>();
        Map<Long, Teacher> teacherMap = teacherList.stream().collect(Collectors.toMap(Teacher::getId, teacher -> teacher, (prex, next) -> next));
        courseList.forEach(course -> {
            CourseListPo courseListPo = ConvertUtils.sourceToTarget(course, CourseListPo.class);
            Optional.ofNullable(teacherMap.get(course.getTeacherId())).ifPresent(user -> {
                courseListPo.setTeacherName(user.getUserName());
            });
            resultList.add(courseListPo);
        });
        return R.ok(resultList);
    }

    @Override
    public R<PageData<CourseAdminListPo>> courseListAPI_003(Condition<CourseAdminListVo> condition) {
        // 构建查询条件
        CourseAdminListVo courseAdminListVo = condition.getCondition();
        QueryPage queryPage = condition.getPage();
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        Page<Course> coursePage = new Page<Course>().setSize(queryPage.getSize()).setCurrent(queryPage.getCurrent());
        // 进行查询
        queryWrapper.lambda().like(Objects.nonNull(courseAdminListVo.getName()), Course::getName, courseAdminListVo.getName())
                .orderByDesc(Course::getCreateTime)
                .eq(Objects.nonNull(courseAdminListVo.getTeacherId()), Course::getTeacherId, courseAdminListVo.getTeacherId())
                .eq(Objects.nonNull(courseAdminListVo.getStatus()), Course::getStatus, courseAdminListVo.getStatus())
                .eq(Objects.nonNull(courseAdminListVo.getFree()), Course::getFree, courseAdminListVo.getFree())
                .eq(Objects.nonNull(courseAdminListVo.getTypeId()), Course::getTypeId, courseAdminListVo.getTypeId());
        // 赋值
        ArrayList<CourseAdminListPo> resultList = new ArrayList<>();
        this.page(coursePage, queryWrapper);
        List<Course> records = coursePage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return R.ok(new PageData<>(resultList, 0L));
        }
        //region 教师map的整合
        Set<Long> teacherIdSet = records.stream().map(Course::getTeacherId).collect(Collectors.toSet());
        List<Teacher> teacherList = teacherService.listByIds(teacherIdSet);
        Map<Long, Teacher> teacherMap = teacherList.stream().collect(Collectors.toMap(Teacher::getId, teacher -> teacher, (prex, next) -> next));
        //endregion

        //region 课程type的整合
        Set<Long> typeIdSet = records.stream().map(Course::getTypeId).collect(Collectors.toSet());
        List<CourseType> courseTypeList = typeService.listByIds(typeIdSet);
        Map<Long, CourseType> courseTypeMap = courseTypeList.stream().collect(Collectors.toMap(CourseType::getId, courseType -> courseType, (prex, next) -> next));
        //endregion

        records.forEach(course -> {
            CourseAdminListPo target = ConvertUtils.sourceToTarget(course, CourseAdminListPo.class);
            Optional.ofNullable(teacherMap.get(course.getTeacherId())).ifPresent(teacher -> {
                target.setTeacherName(teacher.getUserName());
            });
            Optional.ofNullable(courseTypeMap.get(course.getTypeId())).ifPresent(courseType -> {
                target.setTypeName(courseType.getName());
            });
            resultList.add(target);
        });
        return R.ok(new PageData<>(resultList, coursePage.getTotal()));
    }

    @Override
    @Transactional
    public R<String> courseInsertAPI_004(CourseInsertVo courseInsertVo) {
        ValidatorUtils.validateEntity(courseInsertVo);
        Course course = ConvertUtils.sourceToTarget(courseInsertVo, Course.class);
        if (Objects.nonNull(courseInsertVo.getPrice())) {
            BigDecimal decimal = new BigDecimal(100);
            BigDecimal finalPrice = courseInsertVo.getPrice().multiply(decimal);
            course.setPrice(finalPrice);
        }
        this.save(course);
        return R.ok(null, "添加成功");
    }

    @Override
    public R<CourseInsertPo> courseGetByIdAPI_005(Long id) {
        Course course = this.getById(id);
        CourseInsertPo source = ConvertUtils.sourceToTarget(course, CourseInsertPo.class);
        if (Objects.nonNull(course.getPrice())) {
            BigDecimal devide = new BigDecimal(100);
            BigDecimal finalPrice = course.getPrice().divide(devide);
            source.setPrice(finalPrice);
        }
        return R.ok(source, "显示成功");
    }

    @Override
    @Transactional
    public R<String> courseUpdateAPI_006(CourseUpdateVo courseUpdateVo) {
        ValidatorUtils.validateEntity(courseUpdateVo);
        BigDecimal bigDecimal = new BigDecimal(100);
        this.update(new UpdateWrapper<Course>().lambda().eq(Course::getId, courseUpdateVo.getId())
                .set(Course::getTeacherId, courseUpdateVo.getTeacherId())
                .set(Course::getFree, courseUpdateVo.getFree())
                .set(Course::getName, courseUpdateVo.getName())
                .set(Course::getCoverUrl, courseUpdateVo.getCoverUrl())
                .set(Course::getStatus, courseUpdateVo.getStatus())
                .set(Objects.nonNull(courseUpdateVo.getPrice()), Course::getPrice, courseUpdateVo.getPrice().multiply(bigDecimal)));

        return R.ok(null,"更新成功");
    }

    @Override
    @Transactional
    public R<String> courseDeleteAPI_006(Long id) {
        if (!Objects.nonNull(this.getById(id))) {
            throw new RuntimeException("数据库中没有该课程");
        }
        this.removeById(id);
        return R.ok(null,"删除成功");
    }

    @Override
    public R<List> courseDictAPI_008() {
        List<Course> courseList = this.list(new QueryWrapper<Course>());
        List<CourseDictPo> resultList = ConvertUtils.sourceToTarget(courseList, CourseDictPo.class);
        return R.ok(resultList,"字典值");
    }
}
